import pygame

class catClass(pygame.sprite.Sprite):
    
    imgList = {}
    current_x_add = 0
    current_y_add = 0
    frame = 0
    step = 4
    old_step = 0
    time_delta = 0
    images = {}
    frames = {}
    actions = {}
    delay = 3
    pause = 0
    direction = ""
    old_action = 0
    selected_action = 0
    center_vals = {}
    image = None
    rect = None
    jumping_duration = 1000
    jump_height = 150 
    jumping = False
    jumpStart = 0
    
    
    def __init__(self, init_pos = None):
        pygame.sprite.Sprite.__init__(self)

        self.old_step = self.step
        self.old_delay = self.delay        
        self.images = {'width': 115, 'height': 110}
        self.frames = {'per_row': 5, 'cols': 4, 'frame_width': 120, 'frame_height': 160, 'real_frame_width': 115, 'cut_top': 50}
        self.actions = {'stand':0, 'move':1, 'hide':2, 'jump': 3,}
        print init_pos
        if init_pos is None:
            self.center_vals = {'x':80, 'y':250}
        else:
            self.center_vals = {'x':init_pos[0], 'y':init_pos[1]-self.images['height']}
        #self.center_vals = {'x':0, 'y':0}
        # loading images
        self.loadImages()
        
        self.image = self.imgList[str(0)][0]
        self.rect = self.image.get_rect()
        self.half_time = self.jumping_duration / 2
        
        
    def loadImages(self):
        '''Loading all needed images'''
        imgMaster = pygame.image.load("cat_with_legs.png").convert_alpha()
        
        imgSize = (self.images['width'], self.images['height'])
        for col in range(self.frames['cols']):
            self.imgList[str(col)] = []
            self.imgList[str(col)+"_back"] = []
            for i in range(self.frames['per_row']):
                tmpImg = pygame.Surface(imgSize,pygame.SRCALPHA)
                tmpImg.blit(imgMaster, (0, 0), (self.getOffset(i, col), imgSize))
                
                self.imgList[str(col)].append(tmpImg)
                self.imgList[str(col)+"_back"].append(self.flipImage(tmpImg))
    
    
    def getOffset(self, i, col=0):
        '''Get current offset values based on row and column '''
        return (i*self.frames['frame_width'], self.frames['cut_top']+col*self.frames['frame_height'])
    
    
    def flipImage(self, surf, boolx = True, booly = False):
        return pygame.transform.flip(surf, boolx, booly)
    
    def jumpHeightAtTime(self, elapsedTime):
        ''' The height of the jump at the given elapsed time (milliseconds) '''
        return self.center_vals['y']-((-1.0/self.half_time**2)* ((elapsedTime-self.half_time)**2)+1)*self.jump_height
    
    
    def setDelay(self, delay):
        self.old_delay = self.delay
        self.delay = delay
        
        
    def setStep(self, step):
        self.old_step = self.step
        self.step = step
        
        
    def revertStep(self):
        self.step = self.old_step
        
        
    def setXYAdd(self, **args):
        if len(args) <=0:
            self.current_x_add = 0
            self.current_y_add = 0
            return
        
        for key,val in args.items():
            if key == 'x':
                self.current_x_add = val
            if key == 'y':
                self.current_y_add = val
        
        
    def revertDelay(self):
        self.delay = self.old_delay
    
    
    def setupJumping(self, action):
        if self.jumping:
            return
        self.jumping = True
        self.selected_action = self.actions['jump']
        
    
    def directionToInt(self, direction):
        if direction == "":
            return 1;
        else:
            return -1;
    
    
    def setDataForAction(self, action, tick = 0):
        self.direction = action['direction']
        int_direction = self.directionToInt(self.direction)
        
        if not self.jumping:
            self.jumpStart = tick
            self.time_delta = 0
        else:
            self.time_delta = tick - self.jumpStart
            self.setStep(6)
            
        if 'move' in action['action']:
            self.setXYAdd(x=self.step*int_direction)
            self.selected_action = self.actions['move']
            
        if 'stand' in action['action']:
            self.setXYAdd()
            self.selected_action = self.actions['stand']
            self.setDelay(7)
            
        if 'hide' in action['action']:
            self.setXYAdd()
            self.selected_action = self.actions['hide']
            self.setDelay(45)
        
        if 'jump' in action['action']:
            self.setupJumping(action)
        
        if self.jumping:
            self.selected_action = self.actions['jump']
    
    
    def update(self):
        x = self.current_x_add
        y = self.current_y_add
        
        # select frame
        self.pause += 1
        if self.pause >= self.delay:
            self.pause = 0
            self.frame += 1
            if self.frame >= len(self.imgList[str(0)]):
                self.frame = 0
        if self.jumping:
            self.frame = 0
        
        #select image based on frame
        self.image = self.imgList[str(self.selected_action)+self.direction][self.frame]

        self.rect = self.image.get_rect()
        
        self.center_vals['x'] += x
        
        y = self.updateY(y)
        
        self.rect.top = y
        self.rect.left = self.center_vals['x']
        if not self.jumping:
            self.center_vals['y'] = y
        #print self.rect.center
        # clear some data 
        self.setXYAdd()
        self.revertDelay()
        self.revertStep()
        
        
    def updateY(self, y):
        if self.jumping:
            y = self.jumpHeightAtTime(self.time_delta)
            if self.time_delta > self.jumping_duration:
                self.jumping = False
                self.time_delta = 0
                y = self.center_vals['y']
        else:
            y = self.center_vals['y']
        return y
        
        
        
        
        
        
        
        
        
        
